<!DOCTYPE html>

<html lang="en">

<head>
    <title>WebGL 2 Samples - texture_vertex</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div id="info">WebGL 2 Samples - texture_vertex</div>
    <p id="description">This sample demonstrates the use of texture look up operations in a vertex shader for
        displacement mapping. </p>

    <!-- WebGL 2 shaders -->
    <script id="vs" type="x-shader/x-vertex">
        #version 300 es
        #define POSITION_LOCATION 0
        #define NORMAL_LOCATION 1
        #define TEXCOORD_LOCATION 4

        precision highp float;
        precision highp int;

        uniform mat4 mvMatrix;
        uniform mat4 pMatrix;
        uniform sampler2D displacementMap;

        layout(location = POSITION_LOCATION) in vec3 position;
        layout(location = NORMAL_LOCATION) in vec3 normal;
        layout(location = TEXCOORD_LOCATION) in vec2 texcoord;

        out vec2 v_st;
        out vec3 v_position;

        void main()
        {
            v_st = texcoord;
            float height = texture(displacementMap, texcoord).b;
            vec4 displacedPosition = vec4(position, 1.0) + vec4(normal * height, 0.0);
            v_position = vec3(mvMatrix * displacedPosition);
            gl_Position = pMatrix * mvMatrix * displacedPosition;
        }
    </script>

    <script id="fs" type="x-shader/x-fragment">
        #version 300 es
        precision highp float;
        precision highp int;
        precision highp sampler2D;

        uniform sampler2D diffuse;

        in vec2 v_st;
        in vec3 v_position;

        out vec4 color;

        float textureLevel(in sampler2D sampler, in vec2 v_st)
        {
            vec2 size = vec2(textureSize(sampler, 0));

            float levelCount = max(log2(size.x), log2(size.y));

            vec2 dx = dFdx(v_st * size);
            vec2 dy = dFdy(v_st * size);
            float d = max(dot(dx, dx), dot(dy, dy));

            d = clamp(d, 1.0, pow(2.0, (levelCount - 1.0) * 2.0));

            return 0.5 * log2(d);
        }

        void main()
        {
            vec2 sampleCoord = fract(v_st.xy);
            float level = textureLevel(diffuse, v_st);

            // Compute LOD using gradient
            color = textureLod(diffuse, v_st, level);

            // Compute flat normal using gradient
            vec3 fdx = dFdx(v_position);
            vec3 fdy = dFdy(v_position);

            vec3 N = normalize(cross(fdx, fdy));
            color = mix(color, vec4(N, 1.0), 0.5);
        }

    </script>

    <script type="module" src="./texture_vertex.ts">
    </script>
    <div id="highlightedLines" style="display: none">#L44</div>

</body>

</html>